import el from '../utils/el'
import pitchElement from './pitchElement'
import durationElement from './durationElement'
import curveElement from './curveElement'
import tupletElement from './tupletElement'
import box from './box'
import { flatten } from '../utils/helpers'

/**
 * 生成音符的SVG元素
 * @param {Object} noteLayout - 音符的布局信息
 * @param {Object} noteLayout.note - 音符对象
 * @param {Object} noteLayout.pitchLayout - 音高的布局信息
 * @param {Object} noteLayout.durationLayout - 时值的布局信息
 * @param {Object} noteLayout.tieLayout - 连音线的布局信息
 * @param {Object} noteLayout.tupletLayout - 连音记号的布局信息
 * @param {Array} noteLayout.beginSlursLayouts - 开始的滑音布局数组
 * @param {Array} noteLayout.endSlursLayouts - 结束的滑音布局数组
 * @param {Array} noteLayout.lyricsLayouts - 歌词的布局信息数组
 * @returns {Array} 包含所有音符相关元素的数组
 */
export default function noteElement(noteLayout) {
  const { note, pitchLayout, durationLayout,
          tieLayout, tupletLayout,
          beginSlursLayouts, endSlursLayouts, lyricsLayouts } = noteLayout

  // 确定是否显示连音线
  const showTie = tieLayout => {
    if (!tieLayout) {
      return false
    }

    const { tie } =  tieLayout

    return tie.type !== 'end' || tieLayout.showPrev
  }

  // 确定是否显示连音记号
  const showTuplet = tupletLayout => {
    return tupletLayout && tupletLayout.tuplet.type === 'begin'
  }

  // 根据样式参数生成CSS样式字符串
  const getStyle = ({ family, size, anchor }) => {
    return `
      font-family: ${family}
      font-size: ${size}
      text-anchor: ${anchor || 'begin'}
    `
  }

  const elements = {}

  // 设置元素颜色
  const setColor = color => {
    const { lyrics, hyphens } =  elements

    if (lyrics) {
      lyrics.forEach(element => element.style.fill = color)
    }

    if (hyphens) {
      hyphens.forEach(element => element.style.fill = color)
    }
  }

  // 设置音符播放和停止时的颜色变化
  note.onplay = () => setColor('orange')
  note.onstop = () => setColor('black')

  // 创建并返回音符的SVG元素数组
  return el.create('g', [
    // 绘制音高元素
    pitchElement(pitchLayout),
    // 绘制时值元素
    durationElement(durationLayout),

    // 根据条件绘制连音线元素
    showTie(tieLayout) ? curveElement(tieLayout) : [],
    // 根据条件绘制连音记号元素
    showTuplet(tupletLayout) ? tupletElement(tupletLayout) : [],

    // 绘制开始的滑音曲线元素
    beginSlursLayouts ? beginSlursLayouts.map(layout => {
      return curveElement(layout)
    }) : [],

    // 绘制结束的滑音曲线元素
    endSlursLayouts ? flatten(endSlursLayouts.map(layout => {
      return layout.showPrev ? curveElement(layout) : []
    })) : [],

    // 创建并添加歌词文本元素
    lyricsLayouts ? lyricsLayouts.map(layout => {
      return el.push(elements, 'lyrics').create('text', {
        ...layout.cxby, style: getStyle({ ...layout, anchor: 'middle' })
      }, layout.text)
    }) : [],

    // 创建并添加歌词间的连字符元素
    lyricsLayouts ? flatten(lyricsLayouts.map(layout => {
      const { lyric } = layout
      if (!lyric.next) return []

      const { x2, by: y } = layout
      if (lyric.layout.sys !== lyric.next.layout.sys) {
        return el.push(elements, 'hyphens').create('text', {
          x: x2 + 2,
          y,
          style: getStyle(layout)
        }, '-')
      }

      const nlayout = lyric.next.layout
      if (!nlayout) return

      const nx = nlayout.x
      return el.push(elements, 'hyphens').create('text', {
        x: (x2 + nx) / 2,
        y,
        style: getStyle({ ...layout, anchor: 'middle' })
      }, '-')
    })) : []
  ])
}
